package _Pan3D.role
{
	import _Pan3D.base.ObjectBone;
	import _Pan3D.core.CountObject;
	import _Pan3D.core.Quaternion;
	import _Pan3D.display3D.analysis.AnalysisServer;
	import _Pan3D.load.LoadInfo;
	import _Pan3D.load.LoadManager;
	
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;

	public class AnimDataManager
	{
		private var _animDic:Object = new Object;//key:url,value:countobject
		private var _loadFunDic:Object = new Object;
		
		private static var instance:AnimDataManager;
		public function AnimDataManager()
		{
		}
		public static function getInstance():AnimDataManager{
			if(!instance){
				instance = new AnimDataManager;
			}
			return instance;
		}
		public function addAnim(url:String,fun:Function,info:Object):void{
			if(_animDic.hasOwnProperty(url)){
				fun(_animDic[url].obj,info);
				_animDic[url].num++;
			}else{
				if(!_loadFunDic.hasOwnProperty(url)){
					_loadFunDic[url] = new Array;
					var loaderinfo:LoadInfo = new LoadInfo(url,LoadInfo.XML,onAnimLoad,false,url);
					LoadManager.getInstance().addSingleLoad(loaderinfo);
				}
				_loadFunDic[url].push({"fun":fun,"info":info});
			}
		}
		private function onAnimLoad(str:String,url:String):void{
			var animAry:Array = AnalysisServer.getInstance().analysisAnim(str);
			setFrameToMatrix(animAry);
			
			var countobj:CountObject = new CountObject;
			countobj.obj = animAry;
			
			var ary:Array = _loadFunDic[url];
			for each(var obj:Object in ary){
				obj.fun(animAry,obj.info)
				countobj.num++;
			}
			delete _loadFunDic[url];
			
			_animDic[url] = countobj;
			
			//_meshDic[place] = meshData;
		}
		private function setFrameToMatrix(frameAry:Array):void{
			for(var j:int=0;j<frameAry.length;j++){
				var boneAry:Array = frameAry[j];
				
				var Q0:Quaternion=new Quaternion();
				var Q1:Quaternion=new Quaternion();
				var OldQ:Quaternion=new Quaternion();
				var OldM:Matrix3D=new Matrix3D();
				var newM:Matrix3D=new Matrix3D();
				var tempM:Matrix3D=new Matrix3D;
				var tempObj:ObjectBone=new ObjectBone;
				
				for(var i:int=0;i<boneAry.length;i++){
					
					var _M1:Matrix3D=new Matrix3D;
					
					var xyzfarme0:ObjectBone= boneAry[i];
					Q0=new Quaternion(xyzfarme0.qx,xyzfarme0.qy,xyzfarme0.qz);
					Q0.w= getW(Q0.x,Q0.y,Q0.z);
					var sonBone:ObjectBone=xyzfarme0;
					
					if(xyzfarme0.father==-1){
						OldQ=new Quaternion(xyzfarme0.qx,xyzfarme0.qy,xyzfarme0.qz);
						OldQ.w= getW(OldQ.x,OldQ.y,OldQ.z);
						newM=Q0.toMatrix3D();
						newM.appendTranslation(xyzfarme0.tx,xyzfarme0.ty,xyzfarme0.tz);
						//tempM=newM;
						
						xyzfarme0.qw=OldQ.w;
						xyzfarme0.matrix = newM;
						
					}else {
						var fatherBone:ObjectBone=boneAry[xyzfarme0.father];
						OldQ=new Quaternion(fatherBone.qx,fatherBone.qy,fatherBone.qz,fatherBone.qw);
						OldM=OldQ.toMatrix3D();
						OldM.appendTranslation(fatherBone.tx,fatherBone.ty,fatherBone.tz);
						var  tempV:Vector3D=OldM.transformVector(new Vector3D(sonBone.tx,sonBone.ty,sonBone.tz));
						_M1.appendTranslation(tempV.x,tempV.y,tempV.z);
						
						Q1.multiply(OldQ,Q0);
						newM=Q1.toMatrix3D();
						newM.append(_M1);
						tempM=newM;
						
						xyzfarme0.qx=Q1.x;
						xyzfarme0.qy=Q1.y;
						xyzfarme0.qz=Q1.z;
						xyzfarme0.qw=Q1.w;
						
						xyzfarme0.tx=tempV.x;
						xyzfarme0.ty=tempV.y;
						xyzfarme0.tz=tempV.z;
						xyzfarme0.tw=tempV.w;
						
						xyzfarme0.matrix = tempM;
						
					}
					//context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 12+i*4,  tempM, true);
				}
			}
		}
		
		private function getW(x:Number,y:Number,z:Number):Number{
			var t:Number = 1-(x*x + y*y + z*z);
			if(t<0){
				t=0
			}else{
				t = -Math.sqrt(t);
			}
			return t;
		}
		
	}
}